export interface IConfig {
  fps: number
}

export default class RequestAnimationFrame {
  private fps: number
  private readonly callbacks: Map<number, (...args: any[]) => any> = new Map()
  private keys = 0
  private duration: number
  constructor(config: IConfig) {
    this.fps = config.fps
    this.duration = 1000 / this.fps
    this.callbacks = new Map()
    this.run()
  }

  setFps(fps: number) {
    this.fps = fps
    this.duration = 1000 / this.fps
  }

  requestAnimationFrame(cb: any) {
    const key = this.keys++
    this.callbacks.set(key, cb)
    return key
  }

  cancelAnimationFrame(key: any): void {
    this.callbacks.delete(key)
  }

  private run() {
    setTimeout(() => {
      const list = [...this.callbacks.values()]
      this.callbacks.clear()
      this.run()
      for (const fn of list) {
        fn()
      }
    }, this.duration)
  }
}
